﻿extern alias ClusterAgg;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using ClusterAgg.ClusterAggregation.GeneralTools;

namespace WindowsFormsApplication1
{
    class CFileHandler
    {
        public ClusterAgg.ClusterAggregation.Datum.AData[] ReadFile(string path)
        {
            if (path.EndsWith(".txt") || path.EndsWith(".dts"))
            {
                return CDatasetReader.readDataArray(path);
            }

            List<ClusterAgg.ClusterAggregation.Datum.CPixel> objs = new List<ClusterAgg.ClusterAggregation.Datum.CPixel>();
            TextReader tr = new StreamReader(path);

            int Pid = 0;
            while (tr.Peek() >= 0)
            {
                //assuming each line is a pixel
                string str = tr.ReadLine();
                string[] args = str.Split(' ');
                short x, y;
                int rgb;
                short.TryParse(args[0].Trim(), out x);
                short.TryParse(args[1].Trim(), out y);
                int.TryParse(args[2].Trim(), out rgb);
                objs.Add(new ClusterAgg.ClusterAggregation.Datum.CPixel(x, y, rgb) { id = Pid });
                Pid++;
            }
            return objs.ToArray();
        }

        public ClusterAgg.ClusterAggregation.Datum.CPixel[] ReadImage(string path)
        {
            List<ClusterAgg.ClusterAggregation.Datum.CPixel> objs = new List<ClusterAgg.ClusterAggregation.Datum.CPixel>();
            Bitmap bmp = new Bitmap(path);
            
            //grayscale image
            bmp = processImage(bmp);
            //bmp.Save("c:\\tmp\\1.jpg");           

            int Pid = 0;           
            for (Int16 i = 0; i < bmp.Width; i++)
            {
                for (Int16 j = 0; j < bmp.Height; j++)
                {                    
                    objs.Add(new ClusterAgg.ClusterAggregation.Datum.CPixel(i, j, bmp.GetPixel(i, j).R) { id = Pid });
                    Pid++;                    
                }
            }            

            return objs.ToArray();
        }


        public Bitmap processImage(Bitmap image)
        {
            Bitmap returnMap = new Bitmap(image.Width, image.Height,
                                   PixelFormat.Format32bppArgb);
            BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0,
                                     image.Width, image.Height),
                                     ImageLockMode.ReadOnly,
                                     PixelFormat.Format32bppArgb);
            BitmapData bitmapData2 = returnMap.LockBits(new Rectangle(0, 0,
                                     returnMap.Width, returnMap.Height),
                                     ImageLockMode.ReadOnly,
                                     PixelFormat.Format32bppArgb);            
            unsafe
            {
                byte* imagePointer1 = (byte*)bitmapData1.Scan0;
                byte* imagePointer2 = (byte*)bitmapData2.Scan0;
                for (int i = 0; i < bitmapData1.Height; i++)
                {
                    for (int j = 0; j < bitmapData1.Width; j++)
                    {
                        // write the logic implementation here
                        //U = 0.299R + 0.587G + 0.114B
                        byte grscl = (byte)(imagePointer1[0] * 0.299 + imagePointer1[1] * 0.587 + imagePointer1[2] * 0.114);
                        imagePointer2[0] = grscl;
                        imagePointer2[1] = grscl;
                        imagePointer2[2] = grscl;
                        imagePointer2[3] = imagePointer1[3];
                        //4 bytes per pixel
                        imagePointer1 += 4;
                        imagePointer2 += 4;
                    }//end for j
                    //4 bytes per pixel
                    imagePointer1 += bitmapData1.Stride -
                                    (bitmapData1.Width * 4);
                    imagePointer2 += bitmapData1.Stride -
                                    (bitmapData1.Width * 4);
                }//end for i
            }//end unsafe
            returnMap.UnlockBits(bitmapData2);
            image.UnlockBits(bitmapData1);
            return returnMap;
        }//end processImage
    }
}
